package com.google.appengine.a4ieve;

import com.google.appengine.a4ieve.entities.EntityWrapper;
import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Nagornyi
 *         Date: 4/14/14
 */
public class Helper {

    private static final String EMAIL_PATTERN_STRING = "[^@]+";
    private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_PATTERN_STRING);
    private static final String TOTAL = "total";
    private static final Logger LOG = Logger.getLogger(Helper.class.getName());

    public static String getImgEncoded(Object blobProperty) {
        String blobString = Arrays.toString(((Blob)blobProperty).getBytes());

        String[] byteValues = blobString.substring(1, blobString.length() - 1).split(",");
        byte[] bytes = new byte[byteValues.length];

        for (int i = 0, len = bytes.length; i < len; i++) {
            bytes[i] = Byte.valueOf(byteValues[i].trim());
        }

        String str = (new String(bytes)).replaceAll("\\s{1}", "+");
        return str;
    }

    public static String cropEmailId(String email) {
        Matcher matcher = EMAIL_PATTERN.matcher(email);
        matcher.find(); //i am not checking - after all, there just ain't an email address without "@" character
        String emailKey = matcher.group();
        return emailKey.toLowerCase();
    }

    public static JSONObject parseJsonFromRequest(HttpServletRequest request) {
        BufferedReader reader;
        JSONObject output = null;
        try {
            reader = request.getReader();

            StringBuilder requestJson = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                requestJson.append(line);
            }
            output = new JSONObject(requestJson.toString());
            LOG.severe("Input json is " + output.toString());
            request.setAttribute(Const.INNER_JSON, output);
            return output;
        } catch (IOException i) {
            LOG.severe("Exception occurred while parsing input json");
        }
        return output;
    }

    public static <T extends EntityWrapper> JSONArray writeEntitiesToJson(Class<T> clazz, List<Entity> entities, int total, DatastoreService store) {
        JSONArray data = new JSONArray();
        JSONObject totalObject = new JSONObject();
        totalObject.put(TOTAL, total);
        data.put(totalObject);
        try {
            JSONArray output = new JSONArray();
            Constructor<T> constructor = clazz.getConstructor(Entity.class);
            constructor.setAccessible(true);
            for (Entity e : entities) {
                output.put(constructor.newInstance(store.get(e.getKey())).toJson());
            }
            data.put(output);
        } catch (InstantiationException e) {
            LOG.severe("Error creating wrapper via reflection " + e);
        } catch (IllegalAccessException e) {
            LOG.severe("Error creating wrapper via reflection " + e);
        } catch (NoSuchMethodException e) {
            LOG.severe("Error creating wrapper via reflection " + e);
        } catch (InvocationTargetException e) {
            LOG.severe("Error creating wrapper via reflection " + e);
        } catch (EntityNotFoundException e) {
            LOG.severe("Unable to locate entity with key " + e);
        }
        return data;
    }
}
